/*
 ============================================================================
 Name        : c_demo.c
 Author      : gavin
 Version     :
 Copyright   : gavin@xjnu.edu.cn
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/**
 * C语言是面向过程式的语言
 * C语言大小写敏感
 * C语言最新标准为C11，之前为C99
 */

/**
 * 函数声明
 * 函数声明会告诉编译器函数名称以及如何调用
 *
 */
void print();
void data_type();
void variable();
void const_variable();
void storage_classes();
void condition_if();
// 在声明中，参数名称不重要，只有参数的类型是必需的
void condition_switch(char);
void read_data();
void test_function();

int main(void) {

//	data_type();
//	variable();
//	const_variable();
//	storage_classes();
//	condition();
//	condition_if();
//	char grade;
//	scanf("%s", &grade);
//	condition_switch(grade);

	read_data();
//	test_function();
	return EXIT_SUCCESS;
}

/**
 * 函数定义
 */
void print() {
	puts("!!!Hello World!!!");
	printf("hello geyang! \n");
}

/**
 * C语言数据类型：基本类型、枚举类型、void类型、派生类型
 */
void data_type(void) {

	// sizeof() 返回变量存储大小运算符
	// 显示数据类型的存储字节大小，字节为单位
	printf("char 存储大小：%d \n", sizeof(char));
	printf("short 存储大小：%d \n", sizeof(short));
	printf("int 存储大小：%d \n", sizeof(int));
	printf("long 存储大小：%d \n", sizeof(long));
	printf("float 存储大小：%d \n", sizeof(float));
	printf("double 存储大小：%d \n", sizeof(double));

	// 基本类型
	int left_data = 13;
	int right_data = 1;
	float result;

	printf("result 存储大小：%d \n", sizeof(result));
//	printf("result: %f \n", result);
	result = left_data + right_data;
	printf("result: %f \n", result);

}

/**
 * 变量的声明有两种情况：
 * 1.需要建立存储空间。int a在声明的时候就已经建立了存储空间
 * 2.不需要建立存储空间的，使用extern关键字的变量，只是声明，不定义
 *
 * 变量的作用域：
 * 1.局部变量
 * 在函数或块内部的局部变量，当局部变量被定义时，系统不会对其初始化
 * 2.全局变量
 * 在所有函数外部的全局变量，当定义全局变量时，系统会自动对其初始化
 * 虽然全局变量声明时已经被自动初始化，但正确的初始化变量是良好的编程习惯
 * 3.形式参数
 */

// 全局变量
int volumn = 0;

void variable() {

//	extern int a;
//	int b = 0;
	// 局部变量
	int width = 15;
	int length = 20;
	int height = 5;
	// 计算体积
	volumn = width * length * height;
	printf("体积为：%d \n", volumn);
}

/**
 * 常量：值固定不变的变量
 * C语言中有两种定义常量的方式：
 * 1.#define 预处理器
 * 2.const关键字
 */
void const_variable() {

	const float LENGTH = 10.1;
	const float WIDTH = 20.2;

	float area = 0;

	area = LENGTH * WIDTH;
	printf("value of area: %f \n", area);
}

/**
 * 存储类定义C程序中变量/函数的范围（可见性）和生命周期。
 * 这些说明符放置在它们所修饰的类型之前。
 * auto：局部变量的默认存储类。
 * register：用于定义存储在寄存器中，而不是RAM中的局部变量
 * static：指示编译器在程序的生命周期内保持局部变量的存在
 * extern：用于提供一个全局变量的引用，全局变量对所有程序文件都是可见的。
 *
 */
void storage_classes() {

	// 等价 int year
//	auto int year;
	// register意味着变量可能存在寄存器中，但不一定存储在寄存器中，这取决于硬件和实现的限制
//	register int counter;
	//
	static int days = 0;
	days++;
	printf("days: %d \n", days);
}

void condition_if() {

	// if
	int counter = 0;
	float input_data;
	scanf("%f", &input_data);
	if(input_data < 20) {
		counter++;
	}
	printf("counter: %d \n", counter);
}

void condition_switch(char grade) {

	int counter = 0;

	switch(grade) {
	case 'A':
		printf("很棒！");
		counter++;
		break;
	case 'B':
		printf("做得好！");
		counter++;
		break;
	case 'C':
		printf("您通过了！");
		break;
	case 'D':
		printf("在接在励！");
		break;
	default:
		printf("成绩无效！");
	}

	printf("成绩及格共有%d个 \n", counter);
}

void test_function() {

	printf("%f \n", pow(10.0, 2.1));
	printf("%d \n", (int)pow(10.0, 2.1));
	printf("%ld \n", (long)pow(10.0, 2.1));

	printf("%d \n", (int)pow(10.0, 3.0));
	// 保证pow精确
	printf("%d \n", (int)round(10));
}

void read_data() {

	int length = 5;
	int array[length];

	for (int i = 0; i < length; ++i) {
		scanf("%d", &array[i]);
		printf("%d", array[i]);
	}

}
